#ifndef __A_TREE_H
#define __A_TREE_H

#define __DEBUG_MODE

#include <fstream>
#include <cstring>

#ifdef __DEBUG_MODE
#include <iostream>
#endif

const int MAX_DATA_LENGTH = 1024;
/* Holds a list of keys referenced by the Atree node */
struct ResultRing
{
  ResultRing* nextRing;
  char* key;
  char* data;
};

struct KeyRing
{
  KeyRing* nextRing;
  char* key;
};

struct TreeNode
{
  TreeNode* brotherNode;
  TreeNode* childNode;
  KeyRing* keyRing;
  char nodeLabel;
};

class Atree
{
  public:
    Atree();
    ~Atree();
    void loadData(const char* filename);
    void saveData(const char* filename);
    void insertData(const char* key, const char* data, bool ignoreCase);
    void lookupData(const char* key, bool acceptPartial, bool ignoreCase); 
    bool hasData();
    char* returnKey();
    char* returnData();
    void moveNextData();
  private:    
    void destroyRecursively_(TreeNode* treeNode); //Used on cleanup to destroy the tree recursively
    void saveRecursively_(TreeNode* treeNode, std::ofstream& outputStream); //Used to save our tree
    void loadRecursively_(TreeNode* treeNode, TreeNode* parentNode, std::ifstream& inputStream); //Used to load our tree
    void searchRecursively_(TreeNode* treeNode, const char* previousKey); //Used to find partial search hits
    TreeNode* treeNode_; //Our root node
    ResultRing* resultRing_;
};
#endif
/* **** A Note About the File Format ****
 * A tree saves in an ascii format.  This format consists of commands and data.
 * A command is a single letter on its own line For example:
 *
 * R
 *
 * is a command.  The following is a list of commands:
 * R - Recurse (we are moving on to child nodes)
 * U - UnRecurse (move back up)
 * B - Create a brother node
 * L - Set the label of the current node
 * K - Start data
 * . - End data
 */
